package com.hz.tgb.api.invoice.pdf.util;

import com.hz.tgb.file.FileUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * PDF写入
 *
 * @author hezhao on 2018/10/10 17:05
 */
public class PDFWriteUtil {

    private static final Logger logger = LoggerFactory.getLogger(PDFWriteUtil.class);

    /**
     * 合并PDF
     * @param pdfBytes
     * @return
     */
    public static byte[] mergePDF(List<byte[]> pdfBytes) {
        byte[] mergedBytes = null;

        if (CollectionUtils.isNotEmpty(pdfBytes)) {
            try {
                // 实例化PDFMergerUtility类
                PDFMergerUtility PDFmerger = new PDFMergerUtility();
                // 输出流
                ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
                // 设置目标文件，即合并后的文件
                PDFmerger.setDestinationStream(bos);

                for (byte[] pdfByte : pdfBytes) {
                    // 输入流
                    ByteArrayInputStream bis = new ByteArrayInputStream(pdfByte);
                    // 设置源文件
                    PDFmerger.addSource(bis);
                }

                // 合并文档
                PDFmerger.mergeDocuments(null);
                logger.info("Documents merged");

                // 得到最终合并后的字节数组
                mergedBytes = bos.toByteArray();
            } catch (IOException e) {
                logger.error("发票附件生成接口 -> PDF合并出现异常", e);
            }
        }
        return mergedBytes;
    }

    /**
     * 写入图像文件
     * @param imgFiles
     * @param mergedBytes
     * @return
     */
    public static byte[] writeImage(List<File> imgFiles, byte[] mergedBytes) {
        if (CollectionUtils.isNotEmpty(imgFiles)) {

            PDDocument document = null;

            try {
                // 判断之前PDF合并是否有数据产生
                if (ArrayUtils.isNotEmpty(mergedBytes)) {
                    // 加载原有数据
                    document = PDDocument.load(mergedBytes);
                } else {
                    // 创建新文件
                    document = new PDDocument();
                }

                PDPage page;
                PDPageContentStream contentStream = null;
                for (File imgFile : imgFiles) {
                    try {
                        // 创建页面
                        page = new PDPage();
                        document.addPage(page);

                        // 准备内容流
                        contentStream = new PDPageContentStream(document, page);

                        // 创建PDImageXObject对象
                        PDImageXObject pdImage = PDImageXObject.createFromByteArray(document, FileUtil.readFileByBytes(imgFile), FileUtil.getTypePart(imgFile.getName()));

                        int width = pdImage.getWidth();
                        int height = pdImage.getHeight();

                        // 设置页面大小
                        // MediaBox：页面边框, CropBox：修剪边框, ArtBox：对象边框, TrimBox：裁切边框, BleedBox：出血边框, 参考：https://blog.csdn.net/qinguo2000/article/details/23741221
                        PDRectangle pdRectangle = new PDRectangle(width, height);
                        page.setMediaBox(pdRectangle);

                        // 在PDF文档中绘制图像
                        contentStream.drawImage(pdImage, 0, 0);
                        logger.info("Image inserted");


                    } catch (IOException e) {
                        logger.error("发票附件生成接口 -> PDF插入图像出现异常", e);
                    } finally {
                        if (contentStream != null) {
                            // 关闭内容流
                            try {
                                contentStream.close();
                            } catch (IOException e) {
                                logger.error("发票附件生成接口 -> PDPageContentStream关闭出现异常", e);
                            }
                        }
                    }
                }

                // 输出流
                ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
                // 保存文档
                document.save(bos);

                // 得到最终生成的字节数组
                mergedBytes = bos.toByteArray();
            } catch (IOException e) {
                logger.error("发票附件生成接口 -> PDF插入图像保存出现异常", e);
            } finally {
                if (document != null) {
                    // 关闭文件
                    try {
                        document.close();
                    } catch (IOException e) {
                        logger.error("发票附件生成接口 -> PDDocument关闭出现异常", e);
                    }
                }
            }
        }
        return mergedBytes;
    }

}
